#include "catch.hpp"

#include "common/name_lock.h"

#include <thread>

#include "common/timeit.h"
#include "common/fs.h"


using namespace std;
using namespace evm;

TEST_CASE("name_lock tests", "[name_lock]") {
    REQUIRE(NameLock::names().size() == 0);

    {
        NameLock nl("name");
        REQUIRE(NameLock::names().size() == 1);
    }

    REQUIRE(NameLock::names().size() == 0);

    {
        NameLock nl_1("name1");
        NameLock nl_2("name2");
        REQUIRE(NameLock::names().size() == 2);
    }

    REQUIRE(NameLock::names().size() == 0);

    {
        vector<string> v;
        string path = "name_lock";
        thread t1;
        thread t2;
        {
            NameLock nl("name", path);
            NameLock::names();

            t1 = thread([&v, &path] {
                NameLock nl("name", path);
                NameLock::names();
                v.push_back("item2");
                REQUIRE(v.size() >= 2);
                REQUIRE(v[0] == "item1");
            });

            t2 = thread([&v, &path] {
                NameLock nl("name", path);
                NameLock::names();
                v.push_back("item3");
                REQUIRE(v.size() >= 2);
                REQUIRE(v[0] == "item1");
            });

            sleep(0.1);
            v.push_back("item1");
        }
        t1.join();
        t2.join();
        REQUIRE(v.size() == 3);
        REQUIRE(v[0] == "item1");
        REQUIRE(fs::is_directory(path));
        REQUIRE(fs::is_regular_file(fs::path(path) / "name"));
        REQUIRE(fs::is_directory(path));
        fs::remove_all(path);  // clean lock directory
        REQUIRE(!fs::exists(path));
    }

    REQUIRE(NameLock::names().size() == 0);

}
